﻿#include"stdafx.h"
#include "SQLexpression.h"
using namespace boost;
using namespace std;
SqlEx::SqlEx(string ex) {
	Ex = ex;
}

SqlEx::~SqlEx() {
	//delete Vresults;
}
bool SqlEx::check(CServerSocket* pSocket, ServerDB *serverDb, Authority*auth) {
	this->authority = auth;
	this->pSocket = pSocket;
	this->serverDB = serverDb;
	this->user_host = CStringTostring(pSocket->m_userName);
	transform(Ex.begin(), Ex.end(), Ex.begin(), towlower);
	Ex = sql(Ex);

	Ex = Ex + "END";

	string sqlselect = "select.+from.+(where.+)?((group by)?|(order by)?|(having)?)END";
//	create user username@host identified by passwordEND;
	string sqluser = "create user.+@.+identified by .+END";
	string sqlgrant = "grant privileges on.+to.+@.+END";
	string sqldropuser = "drop user .+@.+END";
	string sqlsetpwd = "set password for .+=.+END";
	string sqlshowuser = "show usersEND";

	regex Puser(sqluser);
	regex Pgrant(sqlgrant);
	regex PdropUser(sqldropuser);
	regex Psetpwd(sqlsetpwd);
	regex Pshowuser(sqlshowuser);

	if (regex_search(Ex, Pshowuser)) {
		return ForShowUser();
	}
	if (regex_search(Ex, Psetpwd)) {
		return ForSetPwd();
	}
	if (regex_search(Ex, Puser)) {
		return ForCreateUser();
	}
	if (regex_match(Ex, Pgrant)) {
		return ForGrant();
	}
	if (regex_match(Ex, PdropUser)) {
		return ForDropUser();
	}

	string sqluseDB = "use.+END";                            //*
	string sqlcreateDB = "create database.+END"; //*
	string sqldropDB = "drop database.+END";//*
	string sqlshowDB = "show databasesEND";//*

	string sqlupdate = "update.+set.+where.+END";
	string sqldelete = "delete.+from.+where.+END";
	string sqlinsert = "insert into \\w+ ?\\(.+\\).?values\\(.+\\)END";
	//string sqlselect = "select.+from.+(where.+)?((group by)?|(order by)?|(having)?)END";

	string sqlcreate = "create table.+\\(.+\\)END";//*
	string sqldrop = "drop table.+END";    //*
	string sqlshow = "show tablesEND";//*
	string sqldesc = "desc .+END";//*

	string sqladdfield = "alter table.+add.+END"; 
	string sqldropfield = "alter table.+drop .+END";
	string sqlmodifyfield = "alter table.+modify.+END";
	string sqlindex = "create index.+on.+\\(.+\\)END";


	regex Pdesc(sqldesc);

	if (regex_match(Ex, Pdesc)) {
		return ForDesc();
	}
	regex Pindex(sqlindex);
	if (regex_match(Ex, Pindex)) {
		return ForIndexCreate();
	}
	regex Pmodifyfield(sqlmodifyfield);
	if (regex_match(Ex, Pmodifyfield)) {
		return ForModifyField();
	}
	regex Pdropfield(sqldropfield);
	if (regex_match(Ex, Pdropfield)) {
		return ForDropField();
	}
	regex Paddfield(sqladdfield);
	regex Pshow(sqlshow);
	regex PdropDB(sqldropDB);
	regex PuseDB(sqluseDB);
	regex Pupdate(sqlupdate);
	regex Pdelete(sqldelete);
	regex Pinsert(sqlinsert);
	regex Pcreate(sqlcreate);
	regex Pselect(sqlselect);
	regex Pdrop(sqldrop);
	regex PcreateDB(sqlcreateDB);
	regex PshowDB(sqlshowDB);

	if (regex_match(Ex, Paddfield)) {
		return ForAddField();
	}
	if (regex_match(Ex, Pshow)) {
		return ForShow();
	}
	if (regex_match(Ex, PdropDB)) {
		return ForDropDB();
	}
	if (regex_match(Ex, PshowDB)) {
		return ForShowDB();
	}
	if (regex_match(Ex, PcreateDB)) {
		return ForCreateDB();
	}
	if (regex_match(Ex, PuseDB)) {
		return ForUseDB();
	}
	if (regex_match(Ex, Pupdate)) {
		return  ForUpdate();
	}
	if (regex_match(Ex, Pdelete)) {
		return  ForDelete();
	}
	if (regex_match(Ex, Pinsert)) {
		return ForInsert();
	}
	if (regex_match(Ex, Pcreate)) {
		return ForCreate();
	}
	if (regex_search(Ex, Pselect)) {
		return ForSelect();
	}
	if (regex_match(Ex, Pdrop)) {
		return ForDrop();
	}
	this->pSocket->SendMSG("请检查你的sql语句是否正确，不支持该语句！！");
	return false;
}



//sql预处理，处理语句中多余的空格
string SqlEx::sql(string sql)//语句预处理
{
	const int count = sql.size();
	string b = "";
	int flag = 0;//标记
	int n = 0;
	for (int i = 0; i < count; i++)
	{
		if (sql[i] != ' ')
		{
			b += sql[i];
			n++;
			flag = 1;
		}
		else if (sql[i] == ' '&&flag == 1)
		{
			b += sql[i];
			n++;
			flag = 0;
		}
	}
	if (b[n - 1] == ' ')
		b.erase(n - 1, 1);

	int pos = b.find("values ");
	if (pos != -1)
		b.replace(pos + 6, 1, "");
	while ((pos = b.find("'")) != -1|| (pos = b.find("`")) != -1)
		b.replace(pos, 1, "");
	return b;
}

